package com.xiaotu.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.xiaotu.cache.BindPhoneAndroidDeviceIdCache;
import com.xiaotu.common.BaseController;
import com.xiaotu.constant.VerifyCodeType;
import com.xiaotu.model.PlayerModel;
import com.xiaotu.model.VerifyCodeInfoModel;
import com.xiaotu.service.LoginService;
import com.xiaotu.service.PlayerImageService;
import com.xiaotu.service.PlayerService;
import com.xiaotu.service.VerifyCodeInfoService;
import com.xiaotu.service.redission.RedissionService;
import com.xiaotu.util.TokenUtil;
import com.xiaotu.vo.LoginVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;


/**
 * @author zhangxiao
 * @create 2021-11-11 10:02
 */
@RequestMapping
@RestController
@CrossOrigin
public class LoginController extends BaseController {

    @Autowired
    private LoginService loginService;

    @Autowired
    private VerifyCodeInfoService verifyCodeInfoService;

    @Autowired
    private PlayerImageService playerImageService;

    @Autowired
    private RedissionService redissionService;

    @Autowired
    private PlayerService playerService;

    /**
     * 登录验证
     *
     * @param androidDeviceId 安卓设备ID
     * @param phone           手机号
     * @param verifyCode      验证码
     * @return
     */
    @GetMapping("login")
    public Object login(String androidDeviceId, String phone, String verifyCode) {
        Validator.validateTrue(StrUtil.isNotEmpty(phone), "请输入手机号");
        Validator.validateTrue(StrUtil.isNotEmpty(verifyCode), "请输入验证码");
        if (!verifyCodeInfoService.valiCodeOverTime(phone, VerifyCodeType.LoginOrRegister.getValue()))
            throw new IllegalArgumentException("验证码已失效");
        VerifyCodeInfoModel validInfoModel = verifyCodeInfoService.queryByPhoneAndCode(phone, verifyCode, VerifyCodeType.LoginOrRegister.getValue());
        if (validInfoModel == null)
            throw new IllegalArgumentException("验证码错误");
        PlayerModel checkPhone = loginService.checkPhone(phone);
        if (ObjectUtil.isNull(checkPhone)) {
            playerService.register(phone);
            checkPhone = loginService.checkPhone(phone);
        }
        Map<String, Object> cache = new HashMap<>();
        cache.put("userInfo", checkPhone);
        String token = TokenUtil.createToken(JSONArray.toJSON(cache).toString());
        //校验是否需要通知已登录用户被挤出登录
        if (redissionService.validPhoneAndroidDeviceIdNotice(phone, androidDeviceId))
            BindPhoneAndroidDeviceIdCache.noticeAnotherAndroidDeviceLoginOut(phone, androidDeviceId);
        redissionService.setPhoneToken(phone, token);
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        if (ObjectUtil.isNotNull(checkPhone.getImageId()))
            loginVo.setImageUrl(playerImageService.getImageUrlById(checkPhone.getImageId()));
        BeanUtil.copyProperties(checkPhone, loginVo);
        //设置指定手机号的所有验证码为无效
        verifyCodeInfoService.inValidPhoneCode(phone, VerifyCodeType.LoginOrRegister.getValue());
        return loginVo;
    }

    /**
     * 设置昵称
     *
     * @param request
     * @param nickName
     * @return
     */
    @PostMapping("setNickName")
    public Object setNickName(HttpServletRequest request, String nickName) {
        if (playerService.validNickName(getPhone(request), nickName)) {
            if (redissionService.validNickNameEffective(getPlayerId(request))) {
                redissionService.setNickNameEffectiveTime(getPlayerId(request));
                playerService.setNickName(getPhone(request), nickName);
            } else {
                throw new IllegalArgumentException("昵称30天内只能修改一次");
            }
        } else {
            throw new IllegalArgumentException("昵称已存在");
        }
        return null;
    }

    /**
     * 刷新昵称
     *
     * @return
     */
    @GetMapping("refreshNickName")
    public Object refreshNickName() {
        return playerService.refreshNickName();
    }

    /**
     * 更新认证状态
     */
    @PostMapping("authentication")
    public Object authentication(HttpServletRequest request) {
        playerService.authentication(getPlayerId(request));
        return null;
    }

}
